package com.xyht.sca_s.student_manage_system.modules.rxRegistrationExamine.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.api.R;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonCodeEnum;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonResult;
import com.xyht.sca_s.student_manage_system.common.commonReturn.ResponseResult;
import com.xyht.sca_s.student_manage_system.modules.advanceRegistration.entity.RxAdvanceRegistrationOrg;
import com.xyht.sca_s.student_manage_system.modules.common.entity.SmsImportTask;
import com.xyht.sca_s.student_manage_system.modules.common.entity.SmsImportTaskDetail;
import com.xyht.sca_s.student_manage_system.modules.common.mapper.SmsImportTaskDetailMapper;
import com.xyht.sca_s.student_manage_system.modules.common.mapper.SmsImportTaskMapper;
import com.xyht.sca_s.student_manage_system.modules.rxRegistration.entity.RxRegistrationChargeCategoryDetail;
import com.xyht.sca_s.student_manage_system.modules.rxRegistration.entity.req.RxRegistrationChargeCategoryDetailReq;
import com.xyht.sca_s.student_manage_system.modules.rxRegistrationExamine.entity.RxRegistrationExamineBlackList;
import com.xyht.sca_s.student_manage_system.modules.rxRegistrationExamine.entity.req.RxRegistrationExamineBlackListBatchAddReq;
import com.xyht.sca_s.student_manage_system.modules.rxRegistrationExamine.entity.req.RxRegistrationExamineBlackListReq;
import com.xyht.sca_s.student_manage_system.modules.rxRegistrationExamine.entity.resp.RxRegistrationExamineBlackListResp;
import com.xyht.sca_s.student_manage_system.modules.rxRegistrationExamine.mapper.RxRegistrationExamineBlackListMapper;
import com.xyht.sca_s.student_manage_system.modules.rxRegistrationExamine.service.RxRegistrationExamineBlackListService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import javax.annotation.Resource;

import java.math.BigDecimal;
import java.util.List;
import java.util.concurrent.Future;
import java.util.stream.Collectors;

import static com.xyht.sca_s.student_manage_system.common.util.ParamCheckUtil.isNullOrEmpty;
import static com.xyht.sca_s.student_manage_system.modules.common.constant.TaskDetailReason.*;
import static com.xyht.sca_s.student_manage_system.modules.common.constant.TaskDetailReason.REASON_IMPORT_ERR;
import static com.xyht.sca_s.student_manage_system.modules.common.constant.TaskNameExample.TASK_NAME_EXAMINE_BLACK_LIST_IMPORT;
import static com.xyht.sca_s.student_manage_system.modules.common.constant.TaskNameExample.TASK_NAME_REGISTRATION_CHARGE_CATEGORY_DETAIL_IMPORT;
import static com.xyht.sca_s.student_manage_system.modules.common.constant.TaskStatus.TASK_STATUS_DONE;
import static com.xyht.sca_s.student_manage_system.modules.common.constant.TaskStatus.TASK_STATUS_ERR;
import static com.xyht.sca_s.student_manage_system.modules.common.constant.TaskTypeConstant.TASK_TYPE_EXAMINE_BLACK_LIST_IMPORT;
import static com.xyht.sca_s.student_manage_system.modules.common.constant.TaskTypeConstant.TASK_TYPE_REGISTRATION_CHARGE_CATEGORY_DETAIL_IMPORT;

/**
 * <p>
 * 审核应用学生黑名单 服务实现类
 * </p>
 *
 * @author XYHT
 * @since 2024-05-15
 */
@Service
public class RxRegistrationExamineBlackListServiceImpl extends ServiceImpl<RxRegistrationExamineBlackListMapper, RxRegistrationExamineBlackList> implements RxRegistrationExamineBlackListService {
    @Resource
    private RxRegistrationExamineBlackListMapper rxRegistrationExamineBlackListMapper;
    @Resource
    private SmsImportTaskMapper smsImportTaskMapper;
    @Resource
    private SmsImportTaskDetailMapper smsImportTaskDetailMapper;
    @Resource
    PlatformTransactionManager transactionManager;

    @Override
    public ResponseResult addBlackList(RxRegistrationExamineBlackListReq blackListReq) {
        if (isNullOrEmpty(blackListReq.getStuName(), blackListReq.getStuIdCard())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        //校验学生是否已存在
        List<RxRegistrationExamineBlackList> blacklistList = rxRegistrationExamineBlackListMapper.selectList(new LambdaQueryWrapper<RxRegistrationExamineBlackList>()
                .eq(RxRegistrationExamineBlackList::getStuIdCard, blackListReq.getStuIdCard()));
        if (blacklistList != null && blacklistList.size() > 0) {
            return CommonResult.failed(CommonCodeEnum.STUDENT_EXIST);
        }

        RxRegistrationExamineBlackList addBlackList = new RxRegistrationExamineBlackList();
        BeanUtils.copyProperties(blackListReq, addBlackList);
        rxRegistrationExamineBlackListMapper.insert(addBlackList);
        return CommonResult.success();
    }

    @Override
    @Async
    public Future<ResponseResult> batchAddBlackList(RxRegistrationExamineBlackListBatchAddReq blackListReq, String user_id) {
        if (isNullOrEmpty(blackListReq.getBlacklistList()) || blackListReq.getBlacklistList().size() < 1) {
            return new AsyncResult<>(CommonResult.failed(CommonCodeEnum.INVALID_PARAM));
        }

        //创建导入任务
        SmsImportTask smsImportTask = new SmsImportTask();
        smsImportTask.setTaskName(TASK_NAME_EXAMINE_BLACK_LIST_IMPORT);
        smsImportTask.setUserId(user_id);
        smsImportTask.setTaskType(TASK_TYPE_EXAMINE_BLACK_LIST_IMPORT);
        smsImportTaskMapper.insert(smsImportTask);
        batchBlackList(blackListReq.getBlacklistList(), smsImportTask.getId());
        return new AsyncResult<>(CommonResult.success());
    }

    private void batchBlackList(List<RxRegistrationExamineBlackListReq> blacklistList, String task_id) {
        int OFFSET_ROW = 3;
        int task_status = TASK_STATUS_DONE;
        for (int i = 0; i < blacklistList.size(); i++) {
            //开启事务
            DefaultTransactionDefinition dt = new DefaultTransactionDefinition();
            // 嵌套事务 PROPAGATION_REQUIRES_NEW 每次开启一个新的事务
            dt.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
            // 设置嵌套事务
            TransactionStatus status = transactionManager.getTransaction(dt);
            try {
                RxRegistrationExamineBlackListReq blackListReq = blacklistList.get(i);
                if (isNullOrEmpty(blackListReq.getStuName(), blackListReq.getStuIdCard())) {
                    task_status = TASK_STATUS_ERR;
                    createTeacherImportTaskDetail(task_id, REASON_INVALID_PARAM, (i + OFFSET_ROW) + "");
                    continue;
                }

                List<RxRegistrationExamineBlackList> list = rxRegistrationExamineBlackListMapper.selectList(new LambdaQueryWrapper<RxRegistrationExamineBlackList>()
                        .eq(RxRegistrationExamineBlackList::getStuIdCard, blackListReq.getStuIdCard()));
                if (list != null && list.size() > 0){
                    RxRegistrationExamineBlackList updateBlackList = new RxRegistrationExamineBlackList();
                    BeanUtils.copyProperties(blackListReq, updateBlackList);
                    updateBlackList.setId(list.get(0).getId());
                    rxRegistrationExamineBlackListMapper.updateById(updateBlackList);
                }else{
                    RxRegistrationExamineBlackList addBlackList = new RxRegistrationExamineBlackList();
                    BeanUtils.copyProperties(blackListReq, addBlackList);
                    rxRegistrationExamineBlackListMapper.insert(addBlackList);
                }
                transactionManager.commit(status);
            } catch (Exception e) {
                transactionManager.rollback(status);
                task_status = TASK_STATUS_ERR;
                createTeacherImportTaskDetail(task_id, REASON_IMPORT_ERR, (i + OFFSET_ROW) + "");
            } finally {
                if (status.isNewTransaction() && !status.isCompleted()) {
                    transactionManager.commit(status);
                }
            }
        }

        SmsImportTask smsImportTask = new SmsImportTask();
        smsImportTask.setId(task_id);
        smsImportTask.setStatus(task_status);
        smsImportTaskMapper.updateById(smsImportTask);
    }

    private void createTeacherImportTaskDetail(String id, String reason, String row) {
        SmsImportTaskDetail smsImportTaskDetail = new SmsImportTaskDetail();
        smsImportTaskDetail.setTaskId(id);
        smsImportTaskDetail.setFailReason(reason);
        smsImportTaskDetail.setFailRow(row);
        smsImportTaskDetailMapper.insert(smsImportTaskDetail);
    }

    @Override
    public ResponseResult deleteBlackList(RxRegistrationExamineBlackListReq blackListReq) {
        if (isNullOrEmpty(blackListReq.getId())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }
        rxRegistrationExamineBlackListMapper.deleteById(blackListReq.getId());
        return CommonResult.success();
    }

    @Override
    public ResponseResult updateBlackList(RxRegistrationExamineBlackListReq blackListReq) {
        if (isNullOrEmpty(blackListReq.getId())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        RxRegistrationExamineBlackList blackList = rxRegistrationExamineBlackListMapper.selectById(blackListReq.getId());
        if (blackList == null) {
            return CommonResult.failed(CommonCodeEnum.ENROLLMENT_MANAGEMENT_STUDENT_NOT_EXIST);
        }

        //修改身份证号，校验是否已存在
        if (!isNullOrEmpty(blackListReq.getStuIdCard()) && !blackListReq.getStuIdCard().equals(blackList.getStuIdCard())) {
            List<RxRegistrationExamineBlackList> list = rxRegistrationExamineBlackListMapper.selectList(new LambdaQueryWrapper<RxRegistrationExamineBlackList>()
                    .eq(RxRegistrationExamineBlackList::getStuIdCard, blackListReq.getStuIdCard())
                    .ne(RxRegistrationExamineBlackList::getId, blackListReq.getId()));
            if (list != null && list.size() > 0) {
                return CommonResult.failed(CommonCodeEnum.RX_REGISTRATION_BLACK_LIST_STUDENT_EXIST);
            }
        }

        RxRegistrationExamineBlackList updateBlackList = new RxRegistrationExamineBlackList();
        BeanUtils.copyProperties(blackListReq, updateBlackList);
        rxRegistrationExamineBlackListMapper.updateById(updateBlackList);
        return CommonResult.success();
    }

    @Override
    public ResponseResult getBlackList(String searchStr, Integer pageNum, Integer pageSize) {
        LambdaQueryWrapper<RxRegistrationExamineBlackList> queryWrapper = new LambdaQueryWrapper<>();
        if (!isNullOrEmpty(searchStr)) {
            queryWrapper.and(wrapper ->
                    wrapper.like(RxRegistrationExamineBlackList::getStuName, searchStr)
                            .or()
                            .like(RxRegistrationExamineBlackList::getStuIdCard, searchStr));
        }
        queryWrapper.orderByDesc(RxRegistrationExamineBlackList::getCreateTime);

        Page<RxRegistrationExamineBlackList> page = new Page<>(pageNum, pageSize);
        rxRegistrationExamineBlackListMapper.selectPage(page, queryWrapper);

        List<RxRegistrationExamineBlackListResp> list = page.getRecords()
                .stream()
                .map(item -> {
                    RxRegistrationExamineBlackListResp bloodListResp = new RxRegistrationExamineBlackListResp();
                    BeanUtils.copyProperties(item, bloodListResp);
                    return bloodListResp;
                })
                .collect(Collectors.toList());
        int total = (int) page.getTotal();
        return CommonResult.success(list, total);
    }
}
